﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestXNA3.Resources.Meshes;
using TestXNA3.Resources;
using TestXNA3.Render;
using Microsoft.Xna.Framework;
using System.Runtime.Serialization;

namespace TestXNA3.Components
{
    [Serializable]
    public class StaticMeshComponent : MeshComponent
    {
        private StaticMesh _staticMesh;
        [System.ComponentModel.Category("StaticMeshComponent")]
        public StaticMesh StaticMesh
        {
            get { return _staticMesh; }
            set { _staticMesh = value; }
        }

        private string _meshName;
        [System.ComponentModel.Category("StaticMeshComponent")]
        public string MeshName
        {
            get { return _meshName; }
            set { _meshName = value; if (_meshName.Length > 0) StaticMesh = new StaticMesh(_meshName); Parent = Parent; }
        }

        public StaticMeshComponent(string meshName)
        {
            _meshName = meshName;
            UseAsParentTracer = true;
            StaticMesh = new StaticMesh(meshName);
        }

        public StaticMeshComponent()
        {
            _meshName = "";
            UseAsParentTracer = true;
            StaticMesh = null;
        }

        public override void AddToRenderQueue(SceneRenderer sceneRenderer, ref List<MeshResource> meshes)
        {
            if (StaticMesh == null)
                return;

            StaticMesh.BoundingSphere = BoundingSphere.CreateFromBoundingBox(Parent.BoundingBox);
            StaticMesh.CastShadows = CastShadow;
            StaticMesh.World = Matrix.CreateTranslation(Translation) * Parent.Axis;

            meshes.Add(StaticMesh);
        }

        protected override void parentSet()
        {
            base.parentSet();

            if (Parent == null || StaticMesh == null)
                return;

            //Vector3 bounds = new Vector3(0,0,0);
            //float maxBound = (StaticMesh.Bounds.X > StaticMesh.Bounds.Y) ? StaticMesh.Bounds.X : StaticMesh.Bounds.Y;
            //maxBound = (StaticMesh.Bounds.Z > maxBound) ? StaticMesh.Bounds.Z : maxBound;

            //bounds.X = (maxBound > bounds.X) ? maxBound : bounds.X;
            //bounds.Y = (maxBound > bounds.Y) ? maxBound : bounds.Y;
            //bounds.Z = (maxBound > bounds.Z) ? maxBound : bounds.Z;

            Parent.BoundingBoxSize = StaticMesh.Bounds;
        }

        public override bool Trace(Vector3 start, Vector3 end, ref float T)
        {
            if (StaticMesh != null && StaticMesh.TriMesh != null)
            {
                return StaticMesh.Trace(start, end, ref T);
            }
            else
            {
                return true;
            }
        }

        public override void notifyActorScaleChanged()
        {
            base.notifyActorScaleChanged();

            if (StaticMesh != null)
            {
                StaticMesh.Scale = Parent.Scale;
            }
        }

        public override void Save(System.IO.BinaryWriter writer)
        {
            base.Save(writer);
            writer.Write(_meshName);
            writer.Write(CastShadow);
            StaticMesh.Shader.Save(writer);
        }

        public override void Load(System.IO.BinaryReader reader)
        {
            base.Load(reader);
            _meshName = reader.ReadString();
            MeshName = _meshName;
            CastShadow = reader.ReadBoolean();
            StaticMesh.Shader.Load(reader);
        }

        public override string ToString()
        {
            return MeshName;
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("MeshName", MeshName);
        }
    }
}
